package com.cqs.learning.jvm;

import org.junit.jupiter.api.Assertions;
import org.openjdk.jol.info.ClassLayout;

import java.nio.ByteOrder;
import java.util.function.Function;

/***
 |--------------------------------------------------------------------------------------------------------------|
 |                                              Object Header (128 bits)                                        |
 |--------------------------------------------------------------------------------------------------------------|
 |                        Mark Word (64 bits)                                    |      Klass Word (64 bits)    |
 |--------------------------------------------------------------------------------------------------------------|
 |  unused:25 | identity_hashcode:31 | unused:1 | age:4 | biased_lock:1 | lock:2 |     OOP to metadata object   |  无锁
 |----------------------------------------------------------------------|--------|------------------------------|
 |  thread:54 |         epoch:2      | unused:1 | age:4 | biased_lock:1 | lock:2 |     OOP to metadata object   |  偏向锁
 |----------------------------------------------------------------------|--------|------------------------------|
 |                     ptr_to_lock_record:62                            | lock:2 |     OOP to metadata object   |  轻量锁
 |----------------------------------------------------------------------|--------|------------------------------|
 |                     ptr_to_heavyweight_monitor:62                    | lock:2 |     OOP to metadata object   |  重量锁
 |----------------------------------------------------------------------|--------|------------------------------|
 |                                                                      | lock:2 |     OOP to metadata object   |    GC
 |--------------------------------------------------------------------------------------------------------------|
 * 无锁 001
 * 偏向锁 101
 * 轻量锁 00
 * 重量锁 10
 * GC  11
 *
 * 内存大端小端只要是内存种低位地址存的是高位还是低位
 * 若小地址存的是高位 那么是大端
 * 若小地址存的是低位 那么是小端
 *
 */
public class MarkWord {

    public static final Object objLock = new Object();

    /**
     * "小端模式"
     *
     * 返回8个字符串长度为8的数组
     * 第一个元素result[0]是最低8位
     * 第一个元素result[7]是最高8位
     *
     * @param instance
     * @return
     */
    public static String[] getMarkWord(Object instance) {
        String toPrintable = ClassLayout.parseInstance(instance).toPrintable();
        //64bit
        String[] split = toPrintable.split("\r\n");
        Function<String, String[]> fuc = new Function<String, String[]>() {
            @Override
            public String[] apply(String s) {
                int first = s.indexOf("(");
                int start = s.indexOf("(", first + 1);
                int end = s.indexOf(")", start);
                String str = s.substring(start + 1, end);
                return str.split(" ");
            }
        };
        String[] result = new String[8];
        if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
            System.arraycopy(fuc.apply(split[2]), 0, result, 0, 4);
            System.arraycopy(fuc.apply(split[3]), 0, result, 4, 4);
        }
        return result;
    }

    /**
     * mark 最低三位 可以推出状态
     * @param obj
     * @return
     */
    public static String getMarkWordStatus(Object obj){
        String[] markWord = getMarkWord(obj);
        //最低字节
        String word = markWord[0];
        return word.substring(5);
    }

}
